/*
@(#)LoginController   2024-11-07
 
Copyright (c) 2011-2024 杭州湖畔网络技术有限公司 
保留所有权利 
本软件为杭州湖畔网络技术有限公司所有及包含机密信息，须遵守其相关许可证条款进行使用。
Copyright (c) 2011-2024 HUPUN Network Technology CO.,LTD.
All rights reserved.
This software is the confidential and proprietary information of HUPUN
Network Technology CO.,LTD("Confidential Information").  You shall not
disclose such Confidential Information and shall use it only in
accordance with the terms of the license agreement you entered into with HUPUN.
Website：http://www.hupun.com
*/
package org.obp.upms.controller;

import cn.dev33.satoken.session.SaSession;
import cn.dev33.satoken.stp.SaTokenInfo;
import cn.dev33.satoken.stp.StpUtil;
import cn.hutool.core.util.RandomUtil;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.obp.auth.exception.AuthExceptionEnum;
import org.obp.auth.redis.RedisLoginHelper;
import org.obp.auth.utils.MobileUtils;
import org.obp.core.exception.BizException;
import org.obp.core.result.ApiResult;
import org.obp.data.utils.ObjectUtils;
import org.obp.sms.service.SMSSender;
import org.obp.upms.context.WorkUserHolder;
import org.obp.upms.domain.request.LoginPasswdParam;
import org.obp.upms.domain.request.ResetPasswdParam;
import org.obp.upms.domain.request.SendSmsParam;
import org.obp.upms.domain.response.WorkUserVO;
import org.obp.upms.model.WorkRoleDO;
import org.obp.upms.model.WorkUserDO;
import org.obp.upms.service.WorkRoleService;
import org.obp.upms.service.WorkUserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import java.util.ArrayList;
import java.util.List;

/**
 * @author: Jackey 2024/11/7
 */
@RestController
@RequestMapping("/v1/work/auth")
@Api(tags = {"登录接口"})
public class LoginController {

    @Autowired
    private SMSSender smsSender;
    @Autowired
    private RedisLoginHelper redisLoginHelper;

    @Autowired
    private WorkUserHolder workUserHolder;
    @Autowired
    private WorkUserService workUserService;
    @Autowired
    private WorkRoleService workRoleService;

    @ApiOperation("发送短信验证码")
    @PostMapping("/send/sms")
    public ApiResult<String> sendSms(@RequestBody @Validated SendSmsParam sendSmsParam) {

        String nation = sendSmsParam.getNation().trim();
        String mobile = sendSmsParam.getMobile().trim();
        String type = String.valueOf(sendSmsParam.getType());

        if (!MobileUtils.checkMobile(nation.replaceAll("\\+", ""), mobile)) {
            throw new BizException(AuthExceptionEnum.MOBILE_INCORRECT);
        }

        if (!redisLoginHelper.checkSmsInterval(nation, mobile)) {
            throw new BizException(AuthExceptionEnum.OPERATION_TOO_FREQUENT);
        }
        if (!redisLoginHelper.checkSmsDailyCount(nation, mobile)) {
            throw new BizException(AuthExceptionEnum.OPERATION_TOO_FREQUENT);
        }

        // 发送短信验证码
        String smsCode = RandomUtil.randomNumbers(4);
        boolean success = smsSender.sendSmsCode(nation, mobile, smsCode);
        if (!success) throw new BizException(AuthExceptionEnum.CODE_SEND_FAILURE);

        this.initSmsCode(nation, mobile, smsCode, type);

        return ApiResult.ok();
    }

    private void initSmsCode(String nation, String mobile, String code, String type) {
        redisLoginHelper.createSmsCode(nation, mobile, String.valueOf(type), code);
        redisLoginHelper.delSmsCodeErrorCount(nation, mobile, String.valueOf(type));
        redisLoginHelper.sendSmsInterval(nation, mobile);
        redisLoginHelper.sendSmsDailyCount(nation, mobile);
    }

    @ApiOperation("登录-管理端")
    @PostMapping("/login")
    public ApiResult<String> login(@RequestBody LoginPasswdParam loginPasswdParam) {

        WorkUserDO workUserDO = workUserService.login(loginPasswdParam);

        StpUtil.login(workUserDO.getId());

        SaSession saSession = StpUtil.getSessionByLoginId(workUserDO.getId());
        saSession.set(SaSession.USER, workUserDO);
        List<WorkRoleDO> roleList = new ArrayList<>();
        if (workUserDO.getAdmin() == WorkUserDO.UserAdminEnum.ADMIN.getType()) {
            WorkRoleDO workRoleDO = new WorkRoleDO();
            workRoleDO.setId(WorkUserDO.UserAdminEnum.ADMIN.name());
            roleList.add(workRoleDO);
        }
        List<WorkRoleDO> userRoleList = workRoleService.getRolesByUserId(workUserDO.getId());
        roleList.addAll(userRoleList);
        saSession.set(SaSession.ROLE_LIST, roleList);

        SaTokenInfo tokenInfo = StpUtil.getTokenInfo();
        return ApiResult.ok(tokenInfo.getTokenValue());
    }

    @ApiOperation("登出-管理端")
    @PostMapping("/logout")
    public ApiResult<String> logout() {
        try {
            String token = workUserHolder.getToken();
            StpUtil.logoutByTokenValue(token);
        } catch (BizException ignore) {
        }
        return ApiResult.ok();
    }

    @ApiOperation("登录用户信息")
    @GetMapping("/userInfo")
    public ApiResult<WorkUserVO> userInfo() {

        String userID = workUserHolder.getCurrentUserID();

        WorkUserDO workUserDO = workUserService.getById(userID);
        WorkUserVO workUserVO = ObjectUtils.copy(workUserDO, WorkUserVO.class);

        List<WorkRoleDO> userRoleList = workRoleService.getRolesByUserId(workUserDO.getId());
        workUserVO.setUserRoles(userRoleList);
        return ApiResult.ok(workUserVO);
    }

    @ApiOperation("重置登录密码")
    @PostMapping("/reset/password")
    public ApiResult<String> resetPassword(@RequestBody @Validated ResetPasswdParam resetPasswdParam) {

        workUserService.resetPassword(resetPasswdParam);

        LoginPasswdParam loginPasswdParam = new LoginPasswdParam();
        loginPasswdParam.setNation(resetPasswdParam.getNation());
        loginPasswdParam.setMobile(resetPasswdParam.getMobile());
        loginPasswdParam.setPassword(resetPasswdParam.getPassword());
        return this.login(loginPasswdParam);
    }

}